package com.bnyy.medicalHousekeeper;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroupOverlay;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class PopupWindowHelper {

    public static final String TAG = "PopupWindowHelper";

    public static final int PHOTO_TYPE_NORMAL = 0, PHOTO_TYPE_ID_CARD = 1;

    private static PopupWindowHelper instance;
    private static Activity mActivity;
    private static LayoutInflater mInflater;
    private static boolean autoSetBackgroundOverlay = true;

    private PopupWindowHelper() {

    }

    public static PopupWindowHelper getInstance(Activity activity) {
        return getInstance(activity, true);
    }

    public static PopupWindowHelper getInstance(Activity activity, boolean autoSetBackgroundOverlay) {
        PopupWindowHelper.autoSetBackgroundOverlay = autoSetBackgroundOverlay;
        if (instance == null) {
            instance = new PopupWindowHelper();
        }
        mActivity = activity;
        mInflater = LayoutInflater.from(activity);
        return instance;
    }

    public void showSelectTimePopupWindow(boolean showHourMinute, SelectDateTime.OnSelectTimeListener l) {
        new SelectDateTime().show(showHourMinute, System.currentTimeMillis(), l);
    }

    public void showSelectTimePopupWindow(boolean showHourMinute, long from, SelectDateTime.OnSelectTimeListener l) {
        new SelectDateTime().show(showHourMinute, from, l);
    }

    public void showSelectTimePopupWindow(int type, String title, long from, long to, SelectDateTime.OnSelectTimeListener l) {
        new SelectDateTime().show(type, title, from, to, l);
    }

    public void showSelectTimePopupWindow(int type, String title, long from, long to, boolean reverse, SelectDateTime.OnSelectTimeListener l) {
        new SelectDateTime().show(type, title, from, to, reverse, l);
    }

    public void showSingleSelectPopupWindow(ArrayList<String> options, SingleSelect.Callback l) {
        showSingleSelectPopupWindow("", options, l);
    }

    public void showSingleSelectPopupWindow(String title, ArrayList<String> options, SingleSelect.Callback l) {
        new SingleSelect(title, options, l);
    }

    /**
     * 时间选择弹窗
     */
    public static class SelectDateTime extends Parent {

        public static final int TYPE_YMD = 0;
        public static final int TYPE_YM = 1;
        public static final int TYPE_YMD_TIME = 2;
        public static final int TYPE_TIME = 3;
        public static final int TYPE_SEASON = 4;

        private NumberPicker yPicker, mPicker, dPicker, hPicker, minPicker;

        public interface OnSelectTimeListener {
            void onSelected(String formatTime, long timeMillis, int y, int m, int d, int h, int min);
        }

        SelectDateTime() {
        }

        private void show(boolean showHourMinute, long from, long to, OnSelectTimeListener l) {
            show(showHourMinute, "", from, to, l);
        }

        private void show(String title, long from, long to, OnSelectTimeListener l) {
            show(TYPE_YMD_TIME, title, from, to, l);
        }

        private void show(boolean showHourMinute, String title, long from, long to, OnSelectTimeListener l) {
            show(showHourMinute ? TYPE_YMD_TIME : TYPE_YMD, title, from, to, l);
        }

        private void show(int type, String title, long from, long to, OnSelectTimeListener l) {
            show(type, title, from, to, false, l);
        }

        private void show(int type, String title, long from, long to, boolean reverse, OnSelectTimeListener l) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(from);
            int fromYear = calendar.get(Calendar.YEAR);
            int fromYearMinMonth = calendar.get(Calendar.MONTH);
            int fromYearMinDay = calendar.get(Calendar.DAY_OF_MONTH);
            int fromYearMaxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

            Log.e(TAG, "fromYear = " + fromYear + " fromYearMinMonth = " + fromYearMinMonth + " fromYearMinDay = " + fromYearMinDay);

            if (from < to) {
                calendar.setTimeInMillis(to);
            } else {
                calendar.set(fromYear + 100, 11, 31);
            }
            int toYear = calendar.get(Calendar.YEAR);
            int toYearMaxMonth = calendar.get(Calendar.MONTH);
            int toYearMaxDay = calendar.get(Calendar.DAY_OF_MONTH);

            Log.e(TAG, "toYear = " + toYear + " toYearMaxMonth = " + toYearMaxMonth + " toYearMaxDay = " + toYearMaxDay);

            boolean isSameYear = fromYear == toYear;

            View root = mInflater.inflate(R.layout.pop_win_select_date, null);
            TextView tvTitle = root.findViewById(R.id.tv_title);
            tvTitle.setText(title);

            yPicker = root.findViewById(R.id.picker_year);
            mPicker = root.findViewById(R.id.picker_month);
            dPicker = root.findViewById(R.id.picker_day);
            hPicker = root.findViewById(R.id.picker_hour);
            minPicker = root.findViewById(R.id.picker_minute);
            View viewHourMinute = root.findViewById(R.id.ll_hour_minute);

            boolean showHourMinute = type == TYPE_YMD_TIME || type == TYPE_TIME;

            hPicker.setMaxValue(23);
            hPicker.setMinValue(0);
            hPicker.setValue(0);
            hPicker.setFormatter(i -> i < 10 ? "0" + i : String.valueOf(i));
            fixPicker(hPicker);

            minPicker.setMaxValue(59);
            minPicker.setMinValue(0);
            minPicker.setValue(0);
            minPicker.setFormatter(i -> i < 10 ? "0" + i : String.valueOf(i));
            fixPicker(minPicker);

            root.findViewById(R.id.tv_cancel).setOnClickListener(view -> popupWindow.dismiss());
            root.findViewById(R.id.tv_confirm).setOnClickListener(view -> {
                popupWindow.dismiss();

                int year = yPicker.getValue();

                if (l != null) {
                    int month;
                    int day;
                    if (type == TYPE_SEASON) {
                        month = (mPicker.getValue() + 1) * 3 - 1;
                        day = dPicker.getMaxValue();
                    } else {
                        month = mPicker.getValue();
                        day = dPicker.getValue();
                    }
                    calendar.set(year, month, day, showHourMinute ? hPicker.getValue() : 0, showHourMinute ? minPicker.getValue() : 0, 0);
                    SimpleDateFormat sdf = new SimpleDateFormat(showHourMinute ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd");
                    String formatTime = sdf.format(calendar.getTime());
                    Log.e("SelectDateTime", formatTime + " " + calendar.getTimeInMillis() + " " + " year = " + year + " month = " + (month + 1) + " day = " + day + " hour = " + (showHourMinute ? hPicker.getValue() : 0) + " min = " + (showHourMinute ? minPicker.getValue() : 0));
                    l.onSelected(formatTime, calendar.getTimeInMillis(), year, (month + 1), day, showHourMinute ? hPicker.getValue() : -1, showHourMinute ? minPicker.getValue() : -1);
                }
            });

            yPicker.setMaxValue(toYear);
            yPicker.setMinValue(fromYear);
            yPicker.setFormatter(i -> i + "年");
            yPicker.setValue(reverse ? toYear : fromYear);
            yPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
                @Override
                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                    if (newVal == fromYear) {
                        mPicker.setMinValue(fromYearMinMonth);
                        dPicker.setMinValue(mPicker.getValue() == fromYearMinMonth ? fromYearMinDay : 1);
                    } else {
                        if (mPicker.getMaxValue() != 0) {
                            mPicker.setMinValue(0);
                        }
                        if (dPicker.getMaxValue() != 1) {
                            dPicker.setMinValue(1);
                        }
                    }

                    if (newVal == toYear) {
                        mPicker.setMaxValue(toYearMaxMonth);
                        dPicker.setMaxValue(toYearMaxDay);
                    } else {
                        mPicker.setMaxValue(11);
                        calendar.set(newVal, mPicker.getValue(), 1);
                        dPicker.setMaxValue(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                    }
                }
            });
            fixPicker(yPicker);

            if (reverse) {
                mPicker.setMaxValue(toYearMaxMonth);
                mPicker.setMinValue(0);
                mPicker.setValue(toYearMaxMonth);
            } else {
                mPicker.setMaxValue(isSameYear ? toYearMaxMonth : 11);
                mPicker.setMinValue(fromYearMinMonth);
                mPicker.setValue(fromYearMinMonth);
            }
            mPicker.setFormatter(i -> i + 1 + "月");
            mPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
                @Override
                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
//                    calendar.set(calendar.get(Calendar.YEAR), mPicker.getValue(), 1);
                    int year = yPicker.getValue();
                    if (year == fromYear && picker.getValue() == fromYearMinMonth) {
                        dPicker.setMinValue(fromYearMinDay);
                    } else {
                        dPicker.setMinValue(1);
                    }

                    if (year == toYear && picker.getValue() == toYearMaxMonth) {
                        dPicker.setMaxValue(toYearMaxDay);
                    } else {
                        calendar.set(year, newVal, 1);
                        dPicker.setMaxValue(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                    }
                }
            });
            fixPicker(mPicker);

            if (reverse) {
                dPicker.setMaxValue(toYearMaxDay);
                dPicker.setMinValue(1);
                dPicker.setValue(toYearMaxDay);
            } else {
                if (isSameYear && fromYearMinMonth == toYearMaxMonth) {
                    dPicker.setMaxValue(toYearMaxDay);
                } else {
                    dPicker.setMaxValue(fromYearMaxDay);
                }
                dPicker.setMinValue(fromYearMinDay);
            }
            dPicker.setFormatter(i -> i + "日");
            fixPicker(dPicker);

            if (!showHourMinute) {
                viewHourMinute.setVisibility(View.GONE);
            }

            if (type == TYPE_TIME) {
                yPicker.setVisibility(View.GONE);
                mPicker.setVisibility(View.GONE);
                dPicker.setVisibility(View.GONE);
            } else if (type == TYPE_YMD) {
                hPicker.setVisibility(View.GONE);
                minPicker.setVisibility(View.GONE);
            } else if (type == TYPE_YM || type == TYPE_SEASON) {
                dPicker.setVisibility(View.GONE);
                hPicker.setVisibility(View.GONE);
                minPicker.setVisibility(View.GONE);
            }

            if (type == TYPE_SEASON) {
                showSeason(from, to);
            }

            popupWindow.setContentView(root);
            popupWindow.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
        }

        private void showSeason(long from, long to) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(from);
            int fromYear = calendar.get(Calendar.YEAR);
            int fromYearMinMonth = calendar.get(Calendar.MONTH);
            int fromYearMinDay = calendar.get(Calendar.DAY_OF_MONTH);
            if (from < to) {
                calendar.setTimeInMillis(to);
            } else {
                calendar.set(fromYear + 100, 11, 31);
            }

            int toYear = calendar.get(Calendar.YEAR);
            int toYearMaxMonth = calendar.get(Calendar.MONTH);
            int toYearMaxDay = calendar.get(Calendar.DAY_OF_MONTH);
            int toYearMaxSeason = 0;

            if (toYearMaxMonth > 3 && toYearMaxMonth <= 6) {
                toYearMaxSeason = 1;
            } else if (toYearMaxMonth > 6 && toYearMaxMonth <= 9) {
                toYearMaxSeason = 2;
            } else if (toYearMaxMonth > 9) {
                toYearMaxSeason = 4;
            }

            int finalToYearMaxSeason = toYearMaxSeason;
            yPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
                @Override
                public void onValueChange(NumberPicker numberPicker, int i, int i1) {
                    mPicker.setMaxValue(i1 == toYear ? finalToYearMaxSeason : 3);
                }
            });
            mPicker.setMinValue(0);
            mPicker.setMaxValue(fromYear == toYear ? toYearMaxSeason : 3);
            mPicker.setValue(0);
            mPicker.setFormatter(new NumberPicker.Formatter() {
                @Override
                public String format(int i) {
                    switch (i) {
                        case 0:
                            return "第一季度";
                        case 1:
                            return "第二季度";
                        case 2:
                            return "第三季度";
                        case 3:
                            return "第四季度";
                    }
                    return "";
                }
            });
        }

        private void show(boolean showHourMinute, long from, OnSelectTimeListener l) {
            Calendar c = Calendar.getInstance();
            c.setTime(new Date());
            c.add(Calendar.YEAR, 100);
            show(showHourMinute, from, c.getTimeInMillis(), l);
        }
    }

    /**
     * 单选弹窗
     */
    public static class SingleSelect extends Parent {

        public static abstract class CallBackImpl implements Callback {
            @Override
            public void onSelect(int position) {

            }

            @Override
            public void onSelect(String option, int position) {
                onSelect(position);
            }
        }

        public interface Callback {
            void onSelect(int value);

            void onSelect(String option, int position);

        }

        public SingleSelect(String title, ArrayList<String> options, Callback l) {
            super();
            if (options == null) {
                return;
            }
            if (l == null) {
                return;
            }

            View root = mInflater.inflate(R.layout.pop_win_single_select, null);

            TextView tvTitle = root.findViewById(R.id.tv_title);
            tvTitle.setText(title);

            NumberPicker picker = root.findViewById(R.id.picker);
            root.findViewById(R.id.tv_cancel).setOnClickListener(view -> popupWindow.dismiss());
            root.findViewById(R.id.tv_confirm).setOnClickListener(view -> {
                popupWindow.dismiss();
                int position = picker.getValue();
                l.onSelect(options.get(position), position);
            });

            picker.setMinValue(0);
            picker.setMaxValue(options.size() - 1);
            picker.setFormatter(new NumberPicker.Formatter() {
                @Override
                public String format(int value) {
                    return options.get(value);
                }
            });
            fixPicker(picker);

            popupWindow.setContentView(root);
            popupWindow.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
        }
    }

    public PopupWindow show(View view) {
        Parent parent = new Parent();
        parent.show(view);
        return parent.getPopupWindow();
    }

    public PopupWindow show(View view, int w, int h) {
        Parent parent = new Parent();
        parent.show(view, w, h);
        return parent.getPopupWindow();
    }

    static class Parent {
        PopupWindow popupWindow;

        Parent() {
            if (autoSetBackgroundOverlay) {
                setBackgroundOverlay(mActivity, 0.5f);
            }
            popupWindow = new PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
                @Override
                public void onDismiss() {
                    if (autoSetBackgroundOverlay) {
                        setBackgroundOverlay(mActivity, 0);
                    }
                    autoSetBackgroundOverlay = false;
                }
            });
            popupWindow.setOutsideTouchable(false);
            popupWindow.setBackgroundDrawable(new ColorDrawable());
            popupWindow.setAnimationStyle(R.style.pop_win_anim);
            popupWindow.setFocusable(true);
            popupWindow.setOutsideTouchable(true);
//            popupWindow.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);

            InputMethodManager inputMethodManager = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
            if (inputMethodManager != null) {
                inputMethodManager.hideSoftInputFromWindow(mActivity.getWindow().getDecorView().getWindowToken(), 0);
            }
        }

        public PopupWindow getPopupWindow() {
            return popupWindow;
        }

        public void show(View contentView) {
            popupWindow.setContentView(contentView);
            popupWindow.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
        }

        public void show(View contentView, int w, int h) {
            popupWindow.setWidth(w);
            popupWindow.setHeight(h);
            popupWindow.setContentView(contentView);
            popupWindow.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
        }

        public void show(View contentView, int w, int h, View showAt) {
            popupWindow.setWidth(w);
            popupWindow.setHeight(h);
            popupWindow.setContentView(contentView);
            popupWindow.showAtLocation(showAt, Gravity.BOTTOM, 0, 0);
        }

        public void dismiss() {
            popupWindow.dismiss();
        }
    }

    public static void setBackgroundOverlay(Activity activity, float dimAmount) {
        ViewGroup parent = (ViewGroup) activity.getWindow().getDecorView().getRootView();
        ViewGroupOverlay overlay = parent.getOverlay();
        if (dimAmount <= 0) {
            overlay.clear();
        } else {
            Drawable dim = new ColorDrawable(Color.BLACK);
            dim.setBounds(0, 0, parent.getWidth(), parent.getHeight());
            dim.setAlpha((int) (255 * dimAmount));
            overlay.add(dim);
        }
    }

    private static void fixPicker(NumberPicker picker) {
        Field[] pickerFields = NumberPicker.class.getDeclaredFields();
        for (Field pf : pickerFields) {
            if (pf.getName().equals("mSelectionDivider")) {
                pf.setAccessible(true);
                try {
                    //设置分割线的颜色值
                    pf.set(picker, new ColorDrawable(Color.parseColor("#00000000")));
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;
            }
        }

        final int count = picker.getChildCount();
        for (int i = 0; i < count; i++) {
            View child = picker.getChildAt(i);
            if (child instanceof EditText) {
                try {
                    Field selectorWheelPaintField = NumberPicker.class.getDeclaredField("mSelectorWheelPaint");
                    selectorWheelPaintField.setAccessible(true);
                    ((Paint) selectorWheelPaintField.get(picker)).setColor(Color.parseColor("#30C159"));

                    EditText editText = (EditText) child;

                    editText.setTextColor(Color.parseColor("#30C159"));
                    editText.setEnabled(false);
                    editText.setFocusable(false);
                    editText.setOnClickListener(null);
//                    picker.invalidate();

                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            @SuppressLint("DiscouragedPrivateApi")
            Method method = picker.getClass().getDeclaredMethod("changeValueByOne", boolean.class);
            method.setAccessible(true);
            method.invoke(picker, true);
        } catch (NoSuchMethodException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        picker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
    }
}































